﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Silverlight.Testing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Twilight.ViewModels;
using Twilight.TwitterData;
using System.Collections.Generic;
using Twilight.Views;
using System.Reflection;

namespace Twilight.Tests
{
    [TestClass]
    public class ViewModelsFixture : SilverlightTest
    {
        [TestMethod]
        public void ListViewModelGetsDataProvider()
        {
            TestDataProvider testdp = new TestDataProvider();
            testdp.Initialize("twilightbadge", "100");

            ListViewModel vm = new ListViewModel();

            Assert.AreEqual<string>("twilightbadge", vm.Username);
            Assert.AreEqual<Uri>(new Uri("http://twitter.com/twilightbadge"), vm.FollowUri);
            Assert.IsNull(vm.Avatar);
        }

        [TestMethod]
        public void ListViewModelGetsUpdatedTweets()
        {
            TestDataProvider testdp = new TestDataProvider();
            testdp.Initialize("twilightbadge", "100");

            ListViewModel vm = new ListViewModel();

            testdp.FakeTweetsUpdated(SampleTweets());

            Assert.AreEqual<string>("1001 followers", vm.Followers);
            Assert.AreEqual<int>(3, vm.Tweets.Count);
            Assert.AreEqual<string>("This is some test data for you to work with.", vm.Tweets[0].text);
        }

        [TestMethod]
        public void ListViewModelNotifyPropertyChanged()
        {
            TestDataProvider testdp = new TestDataProvider();
            testdp.Initialize("twilightbadge", "100");
            ListViewModel vm = new ListViewModel();

            List<string> propertyChangedEvents = new List<string>();

            vm.PropertyChanged += (s, e) => { propertyChangedEvents.Add(e.PropertyName); };

            testdp.FakeTweetsUpdated(SampleTweets());

            Assert.AreEqual<int>(3, propertyChangedEvents.Count);
            Assert.IsTrue(propertyChangedEvents.Contains("Followers"));
            Assert.IsTrue(propertyChangedEvents.Contains("Tweets"));
            Assert.IsTrue(propertyChangedEvents.Contains("Avatar"));
        }

        [TestMethod]
        public void RotatingViewModelGetsDataProvider()
        {
            TestDataProvider testdp = new TestDataProvider();
            testdp.Initialize("twilightbadge", "100");

            RotatingViewModel vm = new RotatingViewModel();

            Assert.AreEqual<string>("twilightbadge", vm.Username);
            Assert.AreEqual<Uri>(new Uri("http://twitter.com/twilightbadge"), vm.FollowUri);
            Assert.IsNull(vm.Avatar);
        }

        [TestMethod]
        public void RotatingViewModelGetsUpdatedTweets()
        {
            TestDataProvider testdp = new TestDataProvider();
            testdp.Initialize("twilightbadge", "100");

            RotatingViewModel vm = new RotatingViewModel();

            testdp.FakeTweetsUpdated(SampleTweets());

            Assert.AreEqual<string>("1001 followers", vm.Followers);
        }

        [TestMethod]
        public void RotatingViewModelNotifyPropertyChanged()
        {
            TestDataProvider testdp = new TestDataProvider();
            testdp.Initialize("twilightbadge", "100");
            RotatingViewModel vm = new RotatingViewModel();

            List<string> propertyChangedEvents = new List<string>();

            vm.PropertyChanged += (s, e) => { propertyChangedEvents.Add(e.PropertyName); };

            testdp.FakeTweetsUpdated(SampleTweets());

            Assert.AreEqual<int>(3, propertyChangedEvents.Count);
            Assert.IsTrue(propertyChangedEvents.Contains("Followers"));
            Assert.IsTrue(propertyChangedEvents.Contains("FollowCount"));
            Assert.IsTrue(propertyChangedEvents.Contains("Avatar"));
        }

        [TestMethod, Asynchronous]
        public void RotatingViewModelRotateTweets()
        {
            TestDataProvider testdp = new TestDataProvider();
            testdp.Initialize("twilightbadge", "100");

            SmallView sv = new SmallView();

            this.WaitFor<SmallView>(sv, "Loaded");
            TestPanel.Children.Add(sv);

            RotatingViewModel vm = sv.Resources["tweetData"] as RotatingViewModel;
            
            var container = vm.FindVisualStatesContainer(TestPanel);
            //Assert.IsNotNull(container);

            var loaded = vm.FindStateStoryboard(container, "LoadStates", "Loaded");

            // wait for the property changed on the Current Tweet
            this.WaitFor<Storyboard>(loaded, "Completed");

            BaseViewModel.RootVisual = sv;
            testdp.FakeTweetsUpdated(SampleTweets());

            EnqueueCallback(() => Assert.IsNotNull(vm.CurrentTweet));
            EnqueueCallback(() => Assert.AreEqual<string>("This is some test data for you to work with.", vm.CurrentTweet.text));

            EnqueueTestComplete();
        }

        private Tweet[] SampleTweets()
        {
            List<Tweet> tweets = new List<Tweet>();

            User u = new User() { name = "twilightbadge", profile_image_url = "http://static.twitter.com/images/default_profile_normal.png", followers_count = 1001};

            tweets.Add(new Tweet() { user = u, text = "This is some test data for you to work with.", created_at = DateTime.Now.ToString("ddd MMM dd HH:mm:ss zzz yyyy", null), source = "test" });
            tweets.Add(new Tweet() { user = u, text = "Another sample tweet.", created_at = DateTime.Now.ToString("ddd MMM dd HH:mm:ss zzz yyyy", null), source = "test" });
            tweets.Add(new Tweet() { user = u, text = "A third sample tweet.", created_at = DateTime.Now.ToString("ddd MMM dd HH:mm:ss zzz yyyy", null), source = "test" });


            return tweets.ToArray();
        }
    }
}
